package com.gjxblog.core;

import com.rabbitmq.client.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeoutException;

/***
 *
 */
public class ConnectionFactoryTests {
    //2 创建连接
    Connection connection;

    @Before
    public void before() throws IOException, TimeoutException {
        //1 准备连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("mysql.db.gjxblog.cn");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        //2 创建连接
        connection = connectionFactory.newConnection();
    }
    @Test
    public void testConnectionFactory() throws IOException, TimeoutException {
        System.out.println(connection);
    }

    @Test
    public void testChannel() throws IOException, TimeoutException {
        //3 通过connection创建channel
        Channel channel = connection.createChannel();
        System.out.println(channel);

    }

    /**
     * 声明一个队列
     */
    @Test
    public void testQueue() throws IOException {
        Channel channel = connection.createChannel();
        channel.queueDeclare("test001",true,false,false,null);
    }


    /**
     * 四种模式
     */

    @Test
    public void testDirect() throws IOException, TimeoutException {
        Channel channel = connection.createChannel();
        String msg = "Hello RabbitMQ!";
        channel.basicPublish("","test001",null, msg.getBytes());
    }

    @Test
    public void testTopic() throws IOException, TimeoutException {
        Channel channel = connection.createChannel();
        //3 通过channel发送数据
        String exchangeName = "test_topic_exchange";
        String routingKey = "topic.test";
        String msg = "Hello RabbitMQ!";
        channel.basicPublish(exchangeName,routingKey,null,msg.getBytes());
        channel.close();
    }

    @Test
    public void testFanout() throws IOException {
        Channel channel = connection.createChannel();
        //3 通过channel发送数据
        String exchangeName = "test_fanout_exchange";
        String routingKey = "";
        String msg = "Hello RabbitMQ!";
        channel.basicPublish(exchangeName,routingKey,null,msg.getBytes());
    }

    @Test
    public void testHeaders() throws IOException {
        Channel channel = connection.createChannel();

        //3 通过channel发送数据
        String exchangeName = "test_headers_exchange";
        String routingKey = "";
        String msg = "Hello RabbitMQ!";

        Map<String, Object> heardersMap = new HashMap<String, Object>();
        heardersMap.put("api", "login");
        heardersMap.put("version", 1.2);
        heardersMap.put("random", UUID.randomUUID().toString());
        AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties().builder().headers(heardersMap);
        channel.basicPublish(exchangeName,routingKey,properties.build(),msg.getBytes());
    }

    /**
     * Mandatory 标识
     */
    @Test
    public void testMandatory() throws IOException {
        Channel channel = connection.createChannel();
        //3 通过channel发送数据
        String exchangeName = "test_custom_exchange";
        String routingKey = "custom.save";
        String msg = "Hello RabbitMQ!";

        for (int i = 0; i < 5; i++) {
            //mandatory: 如果为true,则监听器会接收到路由不可达的信息，然后进行后续处理，如果为false,那么broker端字典删除该消息
            channel.basicPublish(exchangeName,routingKey,true,null,msg.getBytes());
        }
    }


    /**
     * return 机制
     */
    @Test
    public void testReturn() throws IOException {
        Channel channel = connection.createChannel();

        String exchangeName = "test_return_exchange";
        String routingKey = "returns.save";
        String routingErrorKey = "abc.save";
        String msg = "Hello RabbitMQ!";

        //新增return 监听器
        channel.addReturnListener(new ReturnListener() {
            @Override
            public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("------------handleReturn---------");
                System.out.println("replyCode: "+replyCode);
                System.out.println("replyText: "+replyText);
                System.out.println("exchange: "+exchange);
                System.out.println("routingKey: "+routingKey);
                System.out.println("properties: "+properties);
                System.out.println("body: "+new String(body));
            }
        });

        //mandatory: 如果为true,则监听器会接收到路由不可达的信息，然后进行后续处理，如果为false,那么broker端字典删除该消息
        channel.basicPublish(exchangeName,routingErrorKey,true,null,msg.getBytes());
    }

    /**
     * 消息如何保障100%投递成功？
     * 幂等性
     * 海量订单产生的业务高峰，如何避免消息的重复消费
     * Confirm确认消息、Return返回消息
     * 自定义消费者
     * 消息的ACK与重回队列
     * 消息的限流
     * TTL消息
     * 死信队列
     */






}
